%{
/* COM IDL Compiler
 * @(#) $Id: lexidl.l 56 2009-01-03 03:45:13Z mo@ilaven.net $
 */

/*
 * Copyright (c) 2008 Mo McRoberts.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The names of the author(s) of this software may not be used to endorse
 *    or promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
 * AUTHORS OF THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 2007, Novell, Inc.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the Novell, Inc. nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * 
 * (c) Copyright 1989 OPEN SOFTWARE FOUNDATION, INC.
 * (c) Copyright 1989 HEWLETT-PACKARD COMPANY
 * (c) Copyright 1989 DIGITAL EQUIPMENT CORPORATION
 * To anyone who acknowledges that this file is provided "AS IS"
 * without any express or implied warranty:
 *                 permission to use, copy, modify, and distribute this
 * file for any purpose is hereby granted without fee, provided that
 * the above copyright notices and this notice appears in all source
 * code copies, and that none of the names of Open Software
 * Foundation, Inc., Hewlett-Packard Company, or Digital Equipment
 * Corporation be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.  Neither Open Software Foundation, Inc., Hewlett-
 * Packard Company, nor Digital Equipment Corporation makes any
 * representations about the suitability of this software for any
 * purpose.
 * 
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "p_comidl.h"

# ifndef YYSTYPE
#  define YYSTYPE char *
# endif

struct yyguts_t;

char shortbuf[256], stringbuf[512];
char *strp;

static void read_c_comment(struct yyguts_t * yyg, void *scanner);

%}

%option noyywrap
%option yylineno
%option reentrant
%option bison-bridge

%x str

delim           [ \t\n\f]
opt_ws          {delim}*
ws              {delim}
letter          [A-Za-z_$]
digit           [0-9]
hex_digit       [0-9A-Fa-f]
id              {letter}({letter}|{digit})*
l_suffix        (l|L)
u_suffix        (u|U)
f_suffix        (u|U)
integer         -?{digit}+(({u_suffix}{l_suffix})|({l_suffix}{u_suffix})|{l_suffix}|{u_suffix})?
c_hex_integer   (0(x|X){hex_digit}*)(({l_suffix}{u_suffix}?)|({u_suffix}{l_suffix}?))?
float           {digit}+\.{digit}+({f_suffix}|{l_suffix})?
octet           {hex_digit}{hex_digit}
octet2          {octet}{octet}
octet_dot       {octet}\.
octet2_dash     {octet2}\-
olduuid         \({opt_ws}{octet2}{octet2}{octet}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet_dot}{octet}{opt_ws}\)
uuid            \({opt_ws}{octet2}{octet2_dash}{octet2_dash}{octet2_dash}{octet2_dash}{octet2}{octet2}{octet2}{opt_ws}\)
other           .

%%
{ws}            { /* No action, and no return */ }
'\n'            { }
":"             {return(COLON);}
","             {return(COMMA);}
".."            {return(DOTDOT);}
"="             {return(EQUAL);}
\[              {return(LBRACKET);}
"("             {return(LPAREN);}
\]              {return(RBRACKET);}
")"             {return(RPAREN);}
";"             {return(SEMI);}
"*"             {return(STAR);}
"{"             {return(LBRACE);}
"??<"           {return(LBRACE);}
"}"             {return(RBRACE);}
"??>"           {return(RBRACE);}
"?"             {return(QUESTION);}
"|"             {return(BAR);}
"||"            {return(BARBAR);}
"<"             {return(LANGLE);}
"<<"            {return(LANGLEANGLE);}
">"             {return(RANGLE);}
">>"            {return(RANGLEANGLE);}
"&"             {return(AMP);}
"&&"            {return(AMPAMP);}
"<="            {return(LESSEQUAL);}
">="            {return(GREATEREQUAL);}
"=="            {return(EQUALEQUAL);}
"^"             {return(CARET);}
"+"             {return(PLUS);}
"-"             {return(MINUS);}
"!"             {return(NOT);}
"!="            {return(NOTEQUAL);}
"/"             {return(SLASH);}
"%"             {return(PERCENT);}
"~"             {return(TILDE);}

\"		{
			strp = stringbuf;
			BEGIN(str);
}

<str>\" {
			BEGIN(INITIAL);
			*strp = 0;
			*yylval = stringbuf;
			return STRING;
}

<str>\\[0-7]{1,3} {
			/* octal escape sequence */
			int result;

			sscanf( yytext + 1, "%o", &result );

			if( result > 0xff)
			{
				idl_module_error(curmod, yyget_lineno(yyscanner), "octal character sequence out of range (%s)", yytext);
			}
			*strp = result;
			strp++;
}

<str>\\[0-9]+ {
			idl_module_error(curmod, yyget_lineno(yyscanner), "invalid escape sequence (%s)", yytext);
        }

<str>\\n  *strp++ = '\n';
<str>\\t  *strp++ = '\t';
<str>\\r  *strp++ = '\r';
<str>\\b  *strp++ = '\b';
<str>\\f  *strp++ = '\f';

<str>\\(.|\n)  *strp++ = yytext[1];

<str>[^\\\n\"]+        {
        char *yptr = yytext;

        while ( *yptr )
                *strp++ = *yptr++;
        }

"/*"    { read_c_comment(yyg, yyscanner); }

{uuid}			{
	strncpy(shortbuf, yytext, sizeof(shortbuf));
	shortbuf[sizeof(shortbuf)-1] = 0;
	*yylval = shortbuf;
	return(UUID);
}

{id}			{
	strncpy(shortbuf, yytext, sizeof(shortbuf));
	shortbuf[sizeof(shortbuf)-1] = 0;
	*yylval = shortbuf;
	return idl_keyword_lookup(yytext);
}

{c_hex_integer}	{
	strncpy(shortbuf, yytext, sizeof(shortbuf));
	shortbuf[sizeof(shortbuf)-1] = 0;
	*yylval = shortbuf;
	return INTEGER_NUMERIC;
}

{integer}	{
	strncpy(shortbuf, yytext, sizeof(shortbuf));
	shortbuf[sizeof(shortbuf)-1] = 0;
	*yylval = shortbuf;
	return INTEGER_NUMERIC;
}

{float}			{
	strncpy(shortbuf, yytext, sizeof(shortbuf));
	shortbuf[sizeof(shortbuf)-1] = 0;
	*yylval = shortbuf;
	return FLOAT_NUMERIC;
}

{other}			{
	idl_module_error(curmod, yyget_lineno(yyscanner), "Parse error near '%s'", yytext);
}

%%

static void
commenteof(struct yyguts_t * yyg, void *yyscanner)
{
	idl_module_error(curmod, yyget_lineno(yyscanner), "Unexpected end of file while parsing C-style comment");
}

static void
read_c_comment(struct yyguts_t * yyg, void *yyscanner)
{
    register int c;

    /* While not EOF look for end of comment */
    while ((c = input(yyscanner)))
    {
        if (c == '*')
        {
            if ((c = input(yyscanner)) == '/')
                break ;
            else
                unput(c);
        }
    }

    /* Didn't find end comment before EOF, issue error */
    if (c == 0) commenteof(yyg, yyscanner);
}
